home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter18 / isohex18_2 / isorenderer.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-18  |  18.7 KB  |  671 lines

  1. //IsoRenderer.cpp
  2.  
  3. #include "IsoRenderer.h"
  4. #include "DDFuncs.h"
  5.  
  6. //constructor
  7. CRenderer::CRenderer()
  8. {
  9.     //blank
  10. }
  11.  
  12. CRenderer::~CRenderer()
  13. {
  14.     //deallocate rectangle list
  15.     delete rcUpdateList;
  16.     //deallocate update map
  17.     delete bMap;
  18. }
  19.  
  20. //surfaces
  21. void CRenderer::SetBackBuffer(LPDIRECTDRAWSURFACE7 lpdds)
  22. {
  23.     //set the back buffer
  24.     lpddsBackBuffer=lpdds;
  25. }
  26.  
  27. void CRenderer::SetFrameBuffer(LPDIRECTDRAWSURFACE7 lpdds)
  28. {
  29.     //set the frame buffer
  30.     lpddsFrameBuffer=lpdds;
  31. }
  32.  
  33. //isohexcore components
  34. void CRenderer::SetPlotter(CTilePlotter* pPlotter)
  35. {
  36.     //set the plotter
  37.     pTilePlotter=pPlotter;
  38. }
  39.  
  40. void CRenderer::SetWalker(CTileWalker* pWalker)
  41. {
  42.     //set the tile walker
  43.     pTileWalker=pWalker;
  44. }
  45.  
  46. void CRenderer::SetMouseMap(CMouseMap* pMMap)
  47. {
  48.     //set the mousemap
  49.     pMouseMap=pMMap;
  50. }
  51.  
  52. void CRenderer::SetScroller(CScroller* pScroll)
  53. {
  54.     //set the scroller
  55.     pScroller=pScroll;
  56. }
  57.  
  58. //update list
  59. void CRenderer::SetUpdateRectCount(int iMaxRects)//sets up the rectangle list
  60. {
  61.     //set the max number of rectangles
  62.     iUpdateRectCount=iMaxRects;
  63.     //allocate the rectangle list
  64.     rcUpdateList=new RECT[iMaxRects];
  65.     //set the index to 0
  66.     iUpdateRectIndex=0;
  67. }
  68.  
  69. //update map
  70. void CRenderer::SetMapSize(int MapWidth,int MapHeight)//sets up the update map
  71. {
  72.     //allocate a new map
  73.     bMap=new bool[MapWidth*MapHeight];
  74.  
  75.     //set the map width and height
  76.     iMapWidth=MapWidth;
  77.     iMapHeight=MapHeight;
  78. }
  79.  
  80. //rendering functions
  81. void CRenderer::SetRenderFunction(RENDERFN RendFunc)
  82. {
  83.     //set the rendering function
  84.     RenderFunction=RendFunc;
  85. }
  86.  
  87. //extent rect
  88. void CRenderer::SetExtentRect(RECT* rcExt)
  89. {
  90.     CopyRect(&rcExtent,rcExt);
  91. }
  92.  
  93. //add rect to list
  94. void CRenderer::AddRect(RECT* prcAdd)
  95. {
  96.     //if there is no more room in the rectangle list, return
  97.     if(iUpdateRectIndex>=iUpdateRectCount) return;
  98.  
  99.     //copy rect
  100.     RECT rcUpdate;
  101.     IntersectRect(&rcUpdate,prcAdd,pScroller->GetScreenSpace());
  102.     //if the update rect is empty, return
  103.     if(IsRectEmpty(&rcUpdate)) return;
  104.  
  105.     //clear out the frame buffer with black in the update region
  106.     DDBLTFX ddbltfx;
  107.     DDBLTFX_ColorFill(&ddbltfx,0);
  108.     lpddsFrameBuffer->Blt(&rcUpdate,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
  109.  
  110.     //add the rect to the list
  111.     CopyRect(&rcUpdateList[iUpdateRectIndex],&rcUpdate);
  112.     iUpdateRectIndex++;//add one to the index
  113.  
  114.     //temp variables for calculations
  115.     POINT ptTemp;
  116.     POINT ptCoarse;
  117.     POINT ptMap;
  118.  
  119.     //calculate the corner points
  120.     POINT ptCornerUpperLeft;
  121.     POINT ptCornerUpperRight;
  122.     POINT ptCornerLowerLeft;
  123.     POINT ptCornerLowerRight;
  124.  
  125.     //upper left
  126.     ptTemp.x=rcUpdate.left;
  127.     ptTemp.y=rcUpdate.top;
  128.     //screen->world
  129.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  130.     //subtract mousemap reference point
  131.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  132.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  133.     //calculate coarse coordinates
  134.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  135.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  136.     //calculate fine cordinates
  137.     ptTemp.x%=pMouseMap->GetWidth();
  138.     ptTemp.y%=pMouseMap->GetHeight();
  139.     //check for negative fine coordinates
  140.     if(ptTemp.x<0) ptCoarse.x--;
  141.     if(ptTemp.y<0) ptCoarse.y--;
  142.     //reset map point
  143.     ptMap.x=0;
  144.     ptMap.y=0;
  145.     //move to the east
  146.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  147.     //assign the corner point
  148.     ptCornerUpperLeft.x=ptMap.x*ptCoarse.x;
  149.     ptCornerUpperLeft.y=ptMap.y*ptCoarse.x;
  150.     //reset map point
  151.     ptMap.x=0;
  152.     ptMap.y=0;
  153.     //move to the south
  154.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  155.     ptCornerUpperLeft.x+=(ptMap.x*ptCoarse.y);
  156.     ptCornerUpperLeft.y+=(ptMap.y*ptCoarse.y);
  157.  
  158.     //upper right
  159.     ptTemp.x=rcUpdate.right;
  160.     ptTemp.y=rcUpdate.top;
  161.     //screen->world
  162.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  163.     //subtract mousemap reference point
  164.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  165.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  166.     //calculate coarse coordinates
  167.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  168.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  169.     //calculate fine cordinates
  170.     ptTemp.x%=pMouseMap->GetWidth();
  171.     ptTemp.y%=pMouseMap->GetHeight();
  172.     //check for negative fine coordinates
  173.     if(ptTemp.x<0) ptCoarse.x--;
  174.     if(ptTemp.y<0) ptCoarse.y--;
  175.     //reset map point
  176.     ptMap.x=0;
  177.     ptMap.y=0;
  178.     //move to the east
  179.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  180.     //assign the corner point
  181.     ptCornerUpperRight.x=ptMap.x*ptCoarse.x;
  182.     ptCornerUpperRight.y=ptMap.y*ptCoarse.x;
  183.     //reset map point
  184.     ptMap.x=0;
  185.     ptMap.y=0;
  186.     //move to the south
  187.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  188.     ptCornerUpperRight.x+=(ptMap.x*ptCoarse.y);
  189.     ptCornerUpperRight.y+=(ptMap.y*ptCoarse.y);
  190.  
  191.     //lower left
  192.     ptTemp.x=rcUpdate.left;
  193.     ptTemp.y=rcUpdate.bottom;
  194.     //screen->world
  195.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  196.     //subtract mousemap reference point
  197.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  198.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  199.     //calculate coarse coordinates
  200.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  201.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  202.     //calculate fine cordinates
  203.     ptTemp.x%=pMouseMap->GetWidth();
  204.     ptTemp.y%=pMouseMap->GetHeight();
  205.     //check for negative fine coordinates
  206.     if(ptTemp.x<0) ptCoarse.x--;
  207.     if(ptTemp.y<0) ptCoarse.y--;
  208.     //reset map point
  209.     ptMap.x=0;
  210.     ptMap.y=0;
  211.     //move to the east
  212.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  213.     //assign the corner point
  214.     ptCornerLowerLeft.x=ptMap.x*ptCoarse.x;
  215.     ptCornerLowerLeft.y=ptMap.y*ptCoarse.x;
  216.     //reset map point
  217.     ptMap.x=0;
  218.     ptMap.y=0;
  219.     //move to the south
  220.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  221.     ptCornerLowerLeft.x+=(ptMap.x*ptCoarse.y);
  222.     ptCornerLowerLeft.y+=(ptMap.y*ptCoarse.y);
  223.  
  224.     //lower right
  225.     ptTemp.x=rcUpdate.right;
  226.     ptTemp.y=rcUpdate.bottom;
  227.     //screen->world
  228.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  229.     //subtract mousemap reference point
  230.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  231.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  232.     //calculate coarse coordinates
  233.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  234.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  235.     //calculate fine cordinates
  236.     ptTemp.x%=pMouseMap->GetWidth();
  237.     ptTemp.y%=pMouseMap->GetHeight();
  238.     //check for negative fine coordinates
  239.     if(ptTemp.x<0) ptCoarse.x--;
  240.     if(ptTemp.y<0) ptCoarse.y--;
  241.     //reset map point
  242.     ptMap.x=0;
  243.     ptMap.y=0;
  244.     //move to the east
  245.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  246.     //assign the corner point
  247.     ptCornerLowerRight.x=ptMap.x*ptCoarse.x;
  248.     ptCornerLowerRight.y=ptMap.y*ptCoarse.x;
  249.     //reset map point
  250.     ptMap.x=0;
  251.     ptMap.y=0;
  252.     //move to the south
  253.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  254.     ptCornerLowerRight.x+=(ptMap.x*ptCoarse.y);
  255.     ptCornerLowerRight.y+=(ptMap.y*ptCoarse.y);
  256.  
  257.     //move the corners away from screenspace one step
  258.     ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_NORTHWEST);
  259.     ptCornerUpperRight=pTileWalker->TileWalk(ptCornerUpperRight,ISO_NORTHEAST);
  260.     ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTHWEST);
  261.     ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTHEAST);
  262.  
  263.     //move the left corners to the west
  264.     ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_WEST);
  265.     ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_WEST);
  266.  
  267.     //move the bottom corners to the south
  268.     ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTH);
  269.     ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTH);
  270.  
  271.     //scan through the tiles
  272.     POINT ptRowStart=ptCornerUpperLeft;
  273.     POINT ptRowEnd=ptCornerUpperRight;
  274.     POINT ptCurrent=ptRowStart;
  275.     DWORD dwRowCount=0;
  276.     for(;;)
  277.     {
  278.         //set current point to rowstart
  279.         ptCurrent=ptRowStart;
  280.  
  281.         //render a row of tiles
  282.         for(;;)
  283.         {
  284.             //check that ptcurrent is an actual map location
  285.             if(ptCurrent.x>=0 && ptCurrent.y>=0 && ptCurrent.x<iMapWidth && ptCurrent.y<iMapHeight)
  286.             {
  287.                 //mark tile for updating
  288.                 bMap[ptCurrent.x+ptCurrent.y*iMapWidth]=true;
  289.             }
  290.  
  291.             //is this the last tile in the row?
  292.             if(ptCurrent.x==ptRowEnd.x && ptCurrent.y==ptRowEnd.y) break;
  293.  
  294.             //walk to the east
  295.             ptCurrent=pTileWalker->TileWalk(ptCurrent,ISO_EAST);
  296.  
  297.         }
  298.  
  299.         //check to see if this is the last row
  300.         if(ptRowStart.x==ptCornerLowerLeft.x && ptRowStart.y==ptCornerLowerLeft.y) break;
  301.  
  302.         //move down a row
  303.         if(dwRowCount&1)
  304.         {
  305.             //odd row
  306.             //move outward
  307.             ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHWEST);
  308.             ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHEAST);
  309.         }
  310.         else
  311.         {
  312.             //even row
  313.             //move inward
  314.             ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHEAST);
  315.             ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHWEST);
  316.         }
  317.  
  318.         //add one to the row count
  319.         dwRowCount++;
  320.     }
  321. }
  322.  
  323. void CRenderer::AddTile(int mapx,int mapy)
  324. {
  325.     //put x and y into a point
  326.     POINT ptMap;
  327.     ptMap.x=mapx;
  328.     ptMap.y=mapy;
  329.     //plot the map coord
  330.     POINT ptPlot=pTilePlotter->PlotTile(ptMap);
  331.     //convert to screen coords
  332.     ptPlot=pScroller->WorldToScreen(ptPlot);
  333.     //get ext rect
  334.     RECT rcUpdate;
  335.     CopyRect(&rcUpdate,&rcExtent);
  336.     //offset by plotted point
  337.     OffsetRect(&rcUpdate,ptPlot.x,ptPlot.y);
  338.     //add to rect list
  339.     AddRect(&rcUpdate);
  340. }
  341.  
  342. //scroll the frame
  343. void CRenderer::ScrollFrame(int scrollx,int scrolly)
  344. {
  345.     //figure out the actual scrollx and scrolly
  346.     POINT ptAnchorOld;
  347.     //grab the current anchor position
  348.     ptAnchorOld.x=pScroller->GetAnchor()->x;
  349.     ptAnchorOld.y=pScroller->GetAnchor()->y;
  350.     //move the anchor
  351.     pScroller->MoveAnchor(scrollx,scrolly);
  352.     //calculate the actual scrollx and scrolly
  353.     scrollx=pScroller->GetAnchor()->x-ptAnchorOld.x;
  354.     scrolly=pScroller->GetAnchor()->y-ptAnchorOld.y;
  355.     //reset the anchor position
  356.     pScroller->GetAnchor()->x=ptAnchorOld.x;
  357.     pScroller->GetAnchor()->y=ptAnchorOld.y;
  358.  
  359.     //rectangle for blitting
  360.     RECT rcSrc;//source RECT(frame buffer)
  361.     RECT rcDst;//destination RECT(back buffer)
  362.     RECT rcUpdateX;//update rect
  363.     RECT rcUpdateY;//update rect
  364.     //set both rects to the screen space
  365.     CopyRect(&rcSrc,pScroller->GetScreenSpace());
  366.     CopyRect(&rcDst,pScroller->GetScreenSpace());
  367.     //set both update rects empty
  368.     SetRectEmpty(&rcUpdateX);
  369.     SetRectEmpty(&rcUpdateY);
  370.     //check the sign of scrollx
  371.     //if scrollx is 0, we need do nothing
  372.     if(scrollx)
  373.     {
  374.         //scrollx is non-zero
  375.         if(scrollx<0)
  376.         {
  377.             //positive scrollx
  378.             //scroll direction: to the right
  379.             //set up an update rect for the left side of the screen
  380.             SetRect(&rcUpdateX,rcDst.left,rcDst.top,rcDst.left-scrollx,rcDst.bottom);
  381.             //adjust the blitting rects
  382.             rcDst.left-=scrollx;
  383.             rcSrc.right+=scrollx;
  384.         }
  385.         else
  386.         {
  387.             //negative scrollx
  388.             //scroll direction: to the left
  389.             //set up an update rect for the right side of the screen
  390.             SetRect(&rcUpdateX,rcDst.right-scrollx,rcDst.top,rcDst.right,rcDst.bottom);
  391.             //adjust the blitting rects
  392.             rcDst.right-=scrollx;
  393.             rcSrc.left+=scrollx;
  394.         }
  395.     }
  396.     //check the sign of scrolly
  397.     //if scrolly is 0, we need do nothing
  398.     if(scrolly)
  399.     {
  400.         //scrolly is non-zero
  401.         if(scrolly<0)
  402.         {
  403.             //negative scrolly
  404.             //scroll direction: down
  405.             //set and update rect for the top of the screen
  406.             SetRect(&rcUpdateY,rcDst.left,rcDst.top,rcDst.right,rcDst.top-scrolly);
  407.             //adjust the blitting rects
  408.             rcDst.top-=scrolly;
  409.             rcSrc.bottom+=scrolly;
  410.         }
  411.         else
  412.         {
  413.             //positive scrolly
  414.             //scroll direction: up
  415.             //set an update rect for the bottom of the screen
  416.             SetRect(&rcUpdateY,rcDst.left,rcDst.bottom-scrolly,rcDst.right,rcDst.bottom);
  417.             //adjust the blitting rects
  418.             rcDst.bottom-=scrolly;
  419.             rcSrc.top+=scrolly;
  420.         }
  421.     }
  422.     //perform the blit(bulk scrolling)
  423.     lpddsBackBuffer->BltFast(rcDst.left,rcDst.top,lpddsFrameBuffer,&rcSrc,DDBLTFAST_WAIT);
  424.     //perform the scroll
  425.     pScroller->MoveAnchor(scrollx,scrolly);
  426.     //add the update rects
  427.     AddRect(&rcUpdateX);
  428.     AddRect(&rcUpdateY);
  429. }
  430.  
  431. //update the frame
  432. void CRenderer::UpdateFrame()
  433. {
  434.     //update rect
  435.     RECT rcUpdate;
  436.     //copy from screenspace
  437.     CopyRect(&rcUpdate,pScroller->GetScreenSpace());
  438.  
  439.     //temp variables for calculations
  440.     POINT ptTemp;
  441.     POINT ptCoarse;
  442.     POINT ptMap;
  443.     POINT ptPlot;
  444.  
  445.     //calculate the corner points
  446.     POINT ptCornerUpperLeft;
  447.     POINT ptCornerUpperRight;
  448.     POINT ptCornerLowerLeft;
  449.     POINT ptCornerLowerRight;
  450.  
  451.     //upper left
  452.     ptTemp.x=rcUpdate.left;
  453.     ptTemp.y=rcUpdate.top;
  454.     //screen->world
  455.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  456.     //subtract mousemap reference point
  457.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  458.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  459.     //calculate coarse coordinates
  460.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  461.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  462.     //calculate fine cordinates
  463.     ptTemp.x%=pMouseMap->GetWidth();
  464.     ptTemp.y%=pMouseMap->GetHeight();
  465.     //check for negative fine coordinates
  466.     if(ptTemp.x<0) ptCoarse.x--;
  467.     if(ptTemp.y<0) ptCoarse.y--;
  468.     //reset map point
  469.     ptMap.x=0;
  470.     ptMap.y=0;
  471.     //move to the east
  472.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  473.     //assign the corner point
  474.     ptCornerUpperLeft.x=ptMap.x*ptCoarse.x;
  475.     ptCornerUpperLeft.y=ptMap.y*ptCoarse.x;
  476.     //reset map point
  477.     ptMap.x=0;
  478.     ptMap.y=0;
  479.     //move to the south
  480.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  481.     ptCornerUpperLeft.x+=(ptMap.x*ptCoarse.y);
  482.     ptCornerUpperLeft.y+=(ptMap.y*ptCoarse.y);
  483.  
  484.     //upper right
  485.     ptTemp.x=rcUpdate.right;
  486.     ptTemp.y=rcUpdate.top;
  487.     //screen->world
  488.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  489.     //subtract mousemap reference point
  490.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  491.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  492.     //calculate coarse coordinates
  493.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  494.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  495.     //calculate fine cordinates
  496.     ptTemp.x%=pMouseMap->GetWidth();
  497.     ptTemp.y%=pMouseMap->GetHeight();
  498.     //check for negative fine coordinates
  499.     if(ptTemp.x<0) ptCoarse.x--;
  500.     if(ptTemp.y<0) ptCoarse.y--;
  501.     //reset map point
  502.     ptMap.x=0;
  503.     ptMap.y=0;
  504.     //move to the east
  505.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  506.     //assign the corner point
  507.     ptCornerUpperRight.x=ptMap.x*ptCoarse.x;
  508.     ptCornerUpperRight.y=ptMap.y*ptCoarse.x;
  509.     //reset map point
  510.     ptMap.x=0;
  511.     ptMap.y=0;
  512.     //move to the south
  513.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  514.     ptCornerUpperRight.x+=(ptMap.x*ptCoarse.y);
  515.     ptCornerUpperRight.y+=(ptMap.y*ptCoarse.y);
  516.  
  517.     //lower left
  518.     ptTemp.x=rcUpdate.left;
  519.     ptTemp.y=rcUpdate.bottom;
  520.     //screen->world
  521.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  522.     //subtract mousemap reference point
  523.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  524.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  525.     //calculate coarse coordinates
  526.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  527.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  528.     //calculate fine cordinates
  529.     ptTemp.x%=pMouseMap->GetWidth();
  530.     ptTemp.y%=pMouseMap->GetHeight();
  531.     //check for negative fine coordinates
  532.     if(ptTemp.x<0) ptCoarse.x--;
  533.     if(ptTemp.y<0) ptCoarse.y--;
  534.     //reset map point
  535.     ptMap.x=0;
  536.     ptMap.y=0;
  537.     //move to the east
  538.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  539.     //assign the corner point
  540.     ptCornerLowerLeft.x=ptMap.x*ptCoarse.x;
  541.     ptCornerLowerLeft.y=ptMap.y*ptCoarse.x;
  542.     //reset map point
  543.     ptMap.x=0;
  544.     ptMap.y=0;
  545.     //move to the south
  546.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  547.     ptCornerLowerLeft.x+=(ptMap.x*ptCoarse.y);
  548.     ptCornerLowerLeft.y+=(ptMap.y*ptCoarse.y);
  549.  
  550.     //lower right
  551.     ptTemp.x=rcUpdate.right;
  552.     ptTemp.y=rcUpdate.bottom;
  553.     //screen->world
  554.     ptTemp=pScroller->ScreenToWorld(ptTemp);
  555.     //subtract mousemap reference point
  556.     ptTemp.x-=pMouseMap->GetReferencePoint()->x;
  557.     ptTemp.y-=pMouseMap->GetReferencePoint()->y;
  558.     //calculate coarse coordinates
  559.     ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
  560.     ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
  561.     //calculate fine cordinates
  562.     ptTemp.x%=pMouseMap->GetWidth();
  563.     ptTemp.y%=pMouseMap->GetHeight();
  564.     //check for negative fine coordinates
  565.     if(ptTemp.x<0) ptCoarse.x--;
  566.     if(ptTemp.y<0) ptCoarse.y--;
  567.     //reset map point
  568.     ptMap.x=0;
  569.     ptMap.y=0;
  570.     //move to the east
  571.     ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
  572.     //assign the corner point
  573.     ptCornerLowerRight.x=ptMap.x*ptCoarse.x;
  574.     ptCornerLowerRight.y=ptMap.y*ptCoarse.x;
  575.     //reset map point
  576.     ptMap.x=0;
  577.     ptMap.y=0;
  578.     //move to the south
  579.     ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
  580.     ptCornerLowerRight.x+=(ptMap.x*ptCoarse.y);
  581.     ptCornerLowerRight.y+=(ptMap.y*ptCoarse.y);
  582.  
  583.     //move the corners away from screenspace one step
  584.     ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_NORTHWEST);
  585.     ptCornerUpperRight=pTileWalker->TileWalk(ptCornerUpperRight,ISO_NORTHEAST);
  586.     ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTHWEST);
  587.     ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTHEAST);
  588.  
  589.     //move the left corners to the west
  590.     ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_WEST);
  591.     ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_WEST);
  592.  
  593.     //move the bottom corners to the south
  594.     ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTH);
  595.     ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTH);
  596.  
  597.     //scan through the tiles
  598.     POINT ptRowStart=ptCornerUpperLeft;
  599.     POINT ptRowEnd=ptCornerUpperRight;
  600.     POINT ptCurrent=ptRowStart;
  601.     DWORD dwRowCount=0;
  602.     for(;;)
  603.     {
  604.         //set current point to rowstart
  605.         ptCurrent=ptRowStart;
  606.  
  607.         //render a row of tiles
  608.         for(;;)
  609.         {
  610.             //plot the tile
  611.             ptPlot=pTilePlotter->PlotTile(ptCurrent);
  612.             ptPlot=pScroller->WorldToScreen(ptPlot);
  613.             //check that ptcurrent is an actual map location
  614.             if(ptCurrent.x>=0 && ptCurrent.y>=0 && ptCurrent.x<iMapWidth && ptCurrent.y<iMapHeight)
  615.             {
  616.                 //is the tile marked?
  617.                 if(bMap[ptCurrent.x+ptCurrent.y*iMapWidth])
  618.                 {
  619.                     //send to rendering function
  620.                     RenderFunction(lpddsFrameBuffer,&rcUpdate,ptPlot.x,ptPlot.y,ptCurrent.x,ptCurrent.y);
  621.                     //rest to unmarked
  622.                     bMap[ptCurrent.x+ptCurrent.y*iMapWidth]=false;
  623.                 }
  624.             }
  625.  
  626.             //is this the last tile in the row?
  627.             if(ptCurrent.x==ptRowEnd.x && ptCurrent.y==ptRowEnd.y) break;
  628.  
  629.             //walk to the east
  630.             ptCurrent=pTileWalker->TileWalk(ptCurrent,ISO_EAST);
  631.  
  632.         }
  633.  
  634.         //check to see if this is the last row
  635.         if(ptRowStart.x==ptCornerLowerLeft.x && ptRowStart.y==ptCornerLowerLeft.y) break;
  636.  
  637.         //move down a row
  638.         if(dwRowCount&1)
  639.         {
  640.             //odd row
  641.             //move outward
  642.             ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHWEST);
  643.             ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHEAST);
  644.         }
  645.         else
  646.         {
  647.             //even row
  648.             //move inward
  649.             ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHEAST);
  650.             ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHWEST);
  651.         }
  652.  
  653.         //add one to the row count
  654.         dwRowCount++;
  655.     }
  656.  
  657.     //render all update rects from frame buffer to back buffer
  658.     for(int iCount=0;iCount<iUpdateRectIndex;iCount++)
  659.     {
  660.         //render update rect
  661.         lpddsBackBuffer->BltFast(rcUpdateList[iCount].left,rcUpdateList[iCount].top,lpddsFrameBuffer,&rcUpdateList[iCount],DDBLTFAST_WAIT);
  662.     }
  663.  
  664.     //render from back buffer to frame buffer
  665.     lpddsFrameBuffer->BltFast(rcUpdate.left,rcUpdate.top,lpddsBackBuffer,&rcUpdate,DDBLTFAST_WAIT);
  666.  
  667.     //set rectangle index to 0
  668.     iUpdateRectIndex=0;
  669. }
  670.  
  671.